
import React, { useState, useRef, useMemo } from 'react';
import SocketWeb, { socketWebUtil } from '../../util/websocket';
import './index.css';

let isAppendLastTag = true;
let lastOffset = 0;

function Socket() {

  const [inp, setInp] = useState('');
  const [list, setList] = useState([]);
  const [shadow, setShadow] = useState(false);
  const inpDom = useRef(null);
  const ws = useMemo(() => new SocketWeb('ws://localhost:8001/'), []);

  ws.handleMessage(data => {
    if (data === 'heart') return; // 心跳约定
    const filterData = JSON.parse(data);
    if (filterData?.data) {
      setList([...list, filterData.data])
    }
  })

  const sendSocket = () => {
    const requestObj = {
      type: 'data',
      data: inp
    }
    ws.handleSendMessage(requestObj)
    setInp('')
  }

  const handleKeyDown = e => {
    const { target, key } = e;
    // 返回结果: [{type: 'text', message: 'xxx'}, {type: 'mention', id: 'xxx'}, ...]
    if (key === '@') {
      // 输入@时候必然是字符串
      setShadow(true);
      // 需要异步，否则拿不到值
      setTimeout(() => {
        // 不支持IE，获取光标最后位置
        lastOffset = target.selectionEnd;
        // 是否在末尾添加@
        if (target.value.length === lastOffset) isAppendLastTag = true;
        else isAppendLastTag = false;
      })
    }
  }

  const handleSelect = e => {
    // 规定：@生成后前后各有1个空格
    socketWebUtil.replaceAt(
      inpDom.current,
      e.target.value,
      isAppendLastTag,
      lastOffset
    );
    setShadow(false)
  }

  return (
    <>
      <input
        placeholder='请输入'
        value={inp}
        onChange={e => setInp(e.target.value)}
        onKeyDown={e => {
          if (e.keyCode === 13) setList([...list, inp]);
        }}
      />
      <button
        onClick={sendSocket}
      >发送</button>
      <ul>
        {list.map((item, i) => (
          <li key={i}>websocket from server message: {item}</li>
        ))}
      </ul>
      <p>消息框：</p>
      <textarea
        ref={inpDom}
        className='edit-div'
        onKeyDown={handleKeyDown}
      />
      {shadow && (
        <select
          onChange={e => handleSelect(e)}
        >
          <option>小红</option>
          <option>小绿</option>
          <option>小紫</option>
        </select>
      )}
    </>
  )
}

export default Socket;